/*
json 格式编码解码

	负责进行data编码，不关心怎么打包，也不关心怎么解析
*/
package json

import (
	"encoding/json"
	"gameServer/packet"

	"github.com/bytedance/sonic"
)

const Name = "json"

// DefaultCodec 默认编码器
var DefaultCodec = &codec{}

// json编解码器
type codec struct {
}

// Name 编码器名称
func (codec) Name() string { return Name }

// Marshal 编码 （Encode的编码用encoding/json）
func (codec) Marshal(v interface{}) ([]byte, error) {
	return sonic.Marshal(v)
}

// Unmarshal 解码 （Decode仍然是encoding/json）
func (codec) Unmarshal(data []byte, v interface{}) error {
	return sonic.Unmarshal(data, v)
}

// 对外接口，编码解码，使用默认编码器

// Marshal 编码
func Marshal(v interface{}) ([]byte, error) {
	return DefaultCodec.Marshal(v)
}

// Unmarshal 解码
func Unmarshal(data []byte, v interface{}) error {
	return DefaultCodec.Unmarshal(data, v)
}

// CodecName 默认编解码器名称（暂定）
func CodecName() string {
	return "default codec : " + DefaultCodec.Name()
}

// 编码消息：将业务数据转为符合packet协议的二进制数据包
// 接收者：*codec（指针接收者，方便后续扩展结构体字段）
// 参数：
//
//	route：uint16 → packet包需要的“路由ID”（指定业务模块，如1=聊天，2=战斗）
//	seq：uint16 → packet包需要的“序列号”（用于消息排序/去重）
//	data：interface{} → 任意类型的业务数据（如struct、map、slice等）
//
// 返回值：
//
//	[]byte → 打包后的二进制数据包
//	error → 编码过程中的错误（如JSON序列化失败）
func (c *codec) Encode(route, seq uint16, data interface{}) ([]byte, error) {
	// 逻辑，先进行json序列化，然后用packet进行打包，data就是实际数据，可能是多样化内容，因此用一个空接口接收
	// 后续经过序列化，会变成一个二进制数据数组，再次解包就需要对应格式进行解包
	jsonData, err := json.Marshal(data)
	if err != nil {
		return nil, err
	}
	return packet.Pack(route, seq, jsonData), nil
}

// 解码消息 将packet协议包中的业务数据解析为具体类型
// 接收者：*Codec（指针接收者，与Encode保持一致）
// 参数：
//
//	pkt：*packet.Packet → 已通过packet.Unpack解包后的协议包（含Body字段，即JSON字节切片）
//	v：interface{} → 用于接收解析结果的“指针类型变量”（如&MoveCmd{}）
//
// 返回值：
//
//	error → 解码过程中的错误（如JSON反序列化失败）
func (c *codec) Decode(pkt *packet.Packet, v interface{}) error {
	// 解码消息只需要解码data部分，其他不需要，解码结果就在v中
	return json.Unmarshal(pkt.Body, v)
}
